home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Source Code
/
Libraries
/
Graphic Elements 3
/
GEQTHack
/
GEQTHack.c
< prev
Wrap
C/C++ Source or Header
|
1995-08-28
|
14KB
|
619 lines
/*
GEQTHack.c
QuickTime Movie as a Graphic Element -- demo
6/10/95
by Al Evans
*/
#include <Movies.h>
#include "GUtilities.h"
#include "GrowWindConst.h"
#include "GraphElements.h"
#include "Rects.h"
#include "GridElement.h"
#include "GEBalls.h"
#include "Meter.h"
#include "GELogo.h"
#include "GEMovie.h"
#include "GEAbout.h"
// Adding sounds
#include "GESound.h"
// Menu Commands
#define rMenuBar 128 /* application's menu bar */
#define mApple 128 /* Apple menu */
#define iAbout 1
#define mFile 129 /* File menu */
#define iQuit 1
#define mEdit 130 /* Edit menu */
#define iUndo 1
#define iCut 3
#define iCopy 4
#define iPaste 5
#define iClear 6
#define mSpecial 131
#define iTiming 1
#define iMeter 2
#define iSingleFrame 3
#define iPlayMovie 4
#define iSoundActive 5
#define rAboutDialog 228
#define rUserAlert 129
#define rPerfAlert 300
// Background PICT resource number
#define rBkgPic 200
// Number of master pointer blocks needed
#define masterBlocksNeeded 10
// Globals
Boolean gFinished;
WindowPtr gAnimWindow;
Boolean gSingleFrame = false;
Boolean gDoOne = false;
Boolean gMeterShown = true;
Rect gWorldBaseRect;
Rect gWorldLimRect;
Boolean gMoviePlaying;
Boolean gSoundActive;
// Performance measurement
#define thirtySeconds 30L * 1000 * 1000 //µsec for timers -- never time out
TMTask gTTimeTask, gATimeTask;
unsigned long gTotalTime = 0, gAnimTime = 0;
// Forward declarations
Boolean Initialize( void );
void Shutdown(void);
void EventLoop( void );
pascal void MaintainSounds(GEWorldPtr world, Ptr soundRec);
main()
{
MaxApplZone();
if ( Initialize() )
EventLoop();
Shutdown();
}
// Initialization and Shutdown
Boolean AdequateSystem(void)
{
OSErr err;
long response;
Boolean ok;
//We need 68020 or better
err = Gestalt(gestaltProcessorType, &response);
ok = (!err) & (response >= gestalt68020);
//We need System 7 or later
err = Gestalt(gestaltSystemVersion, &response);
ok = (!err) & (((response & 0xFFFF) / 256) >= 7);
//We need color QD & offscreen GWorlds
err = Gestalt(gestaltQuickdrawVersion, &response);
ok = ok & (!err) & (response >= gestalt32BitQD);
err = Gestalt(gestaltQuickdrawFeatures, &response);
ok = ok & (!err) & (response >= 3); //hasColor & deep GWorlds
return ok;
}
// Make window centered on main graphic device
WindowPtr MakeWindow(short wHSize, short wVSize)
{
GDHandle mainDevice;
Rect devRect;
short hOffst, vOffst;
Rect windRect;
mainDevice = GetMainDevice();
devRect = (**mainDevice).gdRect;
gWorldLimRect.top = wVSize / 2;
gWorldLimRect.left = wHSize / 2;
gWorldLimRect.bottom = RectHeight(&devRect);
gWorldLimRect.right = RectWidth(&devRect);
hOffst = (devRect.right - devRect.left - wHSize) / 2;
if (hOffst < 0) hOffst = 0;
vOffst = (devRect.bottom - devRect.top - wVSize) / 2;
if (vOffst < 0 ) vOffst = 0;
windRect.left = hOffst;
windRect.right = hOffst + wHSize;
windRect.top = vOffst;
windRect.bottom = vOffst + wVSize;
return NewCWindow(nil, &windRect, "\pQuickTime GE", false, documentProc,
(WindowPtr) -1L, false, 0L);
}
void InitPerformanceTiming(void)
{
// Init Timers
gTTimeTask.tmAddr = nil;
gTTimeTask.tmWakeUp = 0;
gTTimeTask.tmReserved = 0;
gATimeTask.tmAddr = nil;
gATimeTask.tmWakeUp = 0;
gATimeTask.tmReserved = 0;
}
Boolean LoadBackground(GEWorldPtr world)
{
GrafElPtr bkg;
if (bkg = NewGridPICT(world, 'BKG ', 1, rBkgPic, srcCopy, 0, 0, 128, 128))
return true;
return false;
}
Boolean AddGrowBox(GEWorldPtr world)
{
GrafElPtr growBox;
growBox = NewBasicPICT(world, 'GBOX', 32100, 20000, srcCopy,
gWorldBaseRect.right - 15, gWorldBaseRect.bottom - 15);
return (growBox != nil);
}
Boolean InitializeGEWorld(WindowPtr window,
Rect * refRect, Rect *actRect, GESoundPtr sounds)
{
Fixed propH, propV;
Fixed worldScale;
GEWorldPtr animWorld;
propH = (RectWidth(actRect) * 65536) / RectWidth(refRect);
propV = (RectHeight(actRect) * 65536) / RectHeight(refRect);
worldScale = (propH > propV?propH:propV);
animWorld = NewGEWorld(window, refRect, worldScale , nil);
if (animWorld == nil) {
TellUser("\pCould not create new GEWorld.", 0);
return false;
}
// Set for automatic sound maintenance
SetPostProcFunc(animWorld, MaintainSounds, (Ptr) sounds);
if (!LoadBackground(animWorld)) {
TellUser("\pCould not load background", 0);
return false;
}
if (!InitBallGraphics(animWorld)) {
TellUser("\pCould not load test graphic", 0);
return false;
}
if (!LoadUsageMeterScene(animWorld)) {
TellUser("\pCould not load usage meter", 0);
return false;
}
if (!LoadQTMovieScene(animWorld)) {
TellUser("\pCould not load QT movie", 0);
return false;
}
if (!LoadLogoScene(animWorld)) {
TellUser("\pCould not load GE logo", 0);
return false;
}
if (!AddGrowBox(animWorld)) {
TellUser("\pCould not add grow box", 0);
return false;
}
// Reposition meter a little to the left
MoveElement(animWorld, meterBkgID, -100, 0);
SetWRefCon(gAnimWindow, (long) animWorld);
gMoviePlaying = false;
return true;
}
Boolean Initialize(void)
{
Rect animRect;
GEWorldPtr animWorld;
GESoundPtr animWorldSounds;
gFinished = false;
gSoundActive = true;
InitSystem(masterBlocksNeeded);
EnterMovies();
if (!AdequateSystem()) {
TellUser("\pSorry, more powerful system required", 0);
return false;
}
if (!LoadMenus(rMenuBar)) {
TellUser("\pCould not load menus", 0);
return false;
}
gAnimWindow = MakeWindow(512, 364);
if (gAnimWindow == nil) {
TellUser("\pCould not create window", 0);
return false;
}
animWorldSounds = GEInitSounds(4);
if (animWorldSounds == nil) {
TellUser("\pCould not initialize sounds", 0);
return false;
}
SetRect(&gWorldBaseRect, 0, 0, 512, 364);
animRect = gWorldBaseRect;
if (!InitializeGEWorld(gAnimWindow, &gWorldBaseRect, &animRect, animWorldSounds)) {
TellUser("\pCould not create animated world.", 0);
return false;
}
InitPerformanceTiming();
ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), true);
ShowWindow(gAnimWindow);
return true;
}
void Shutdown(void)
{
GEWorldPtr world = (GEWorldPtr) GetWRefCon(gAnimWindow);
if (world) {
if (world->userData)
GEDisposeSounds((GESoundPtr) world->userData);
DisposeGEWorld(world);
}
ExitToShell();
}
// Actions
void ChangeWorldSize(WindowPtr window, short newWidth, short newHeight)
{
Rect animRect;
GEWorldPtr world = (GEWorldPtr) GetWRefCon(window);
// Save sounds Ptr
GESoundPtr sounds = (GESoundPtr) world->userData;
DisposeGEWorld(world);
SetRect(&animRect, 0, 0, newWidth, newHeight);
if (!InitializeGEWorld(window, &gWorldBaseRect, &animRect, sounds)) {
TellUser("\pCould not resize animated world.", 0);
ExitToShell();
}
world = (GEWorldPtr) GetWRefCon(window);
ActivateWorld(world, true);
}
pascal void MaintainSounds(GEWorldPtr world, Ptr soundRec)
{
GESoundMaintenance((GESoundPtr) soundRec);
}
void RunMeterAnimation(short ms)
{
static short setting = 0;
if (gMeterShown && (ms > 1)) {
if (ms == setting)
return;
if (ms > setting)
setting++;
else
if (ms < setting)
setting--;
SetMeterReading((GEWorldPtr) GetWRefCon(gAnimWindow), 2 * setting);
}
}
void DisplayPerformance(long frames, long seconds)
{
Str255 framesString, secondsString, fpsString;
long fps;
NumToString(frames, framesString);
NumToString(seconds, secondsString);
fps = (seconds > 0) ? frames / seconds : frames;
NumToString(fps, fpsString);
ParamText(framesString, secondsString, fpsString, "\p");
NoteAlert(rPerfAlert, nil);
}
void SetUpdateInterval(GEWorldPtr world, short newInterval)
{
short ballCount;
GrafElPtr aBall;
for (ballCount = 0; ballCount < numberOfBalls; ballCount++) {
aBall = FindElementByID(world, firstRBID + ballCount);
if (aBall != nil)
aBall->changeIntrvl = newInterval;
aBall = FindElementByID(world, firstBBID + ballCount);
if (aBall != nil)
aBall->changeIntrvl = newInterval;
}
}
void DoTimingLoop(void)
{
long ticks;
unsigned long frames, seconds;
GEWorldPtr world = (GEWorldPtr) GetWRefCon(gAnimWindow);
SetUpdateInterval(world, 1);
StartGETimer(world);
ticks = TickCount();
for (frames = 0; ((TickCount() - ticks) < (30 * 60)) && (!Button()); frames++) {
DoWorldUpdate(world, false);
}
seconds = ((TickCount() - ticks) / 60);
DisplayPerformance(frames, seconds);
SetUpdateInterval(world, 33);
}
// Event Handling
void EventLoop( void )
{
Boolean gotEvent;
EventRecord event;
void DoEvent (EventRecord *event);
void AdjustCursor( void);
do {
InsTime( (QElemPtr) &gTTimeTask);
InsTime( (QElemPtr) &gATimeTask);
PrimeTime( (QElemPtr) &gTTimeTask, -thirtySeconds);
if (!gSingleFrame || gDoOne) {
PrimeTime( (QElemPtr) &gATimeTask, -thirtySeconds);
DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
RmvTime( (QElemPtr) &gATimeTask);
gAnimTime = (thirtySeconds + gATimeTask.tmCount) / 1000;
gDoOne = false;
}
AdjustCursor();
if (gotEvent = WaitNextEvent(everyEvent, &event, 0L, nil))
DoEvent(&event);
RmvTime( (QElemPtr) &gTTimeTask);
gTotalTime = (thirtySeconds + gTTimeTask.tmCount) / 1000; //milliseconds
RunMeterAnimation(gAnimTime);
} while (!gFinished);
}
void DoEvent (EventRecord *event)
{
short part;
WindowPtr window;
char key;
long newWSize;
//Prototypes
void AdjustMenus( void );
void DoMenuCommand(long menuResult);
void DoActivate(WindowPtr window, Boolean becomingActive);
void DoUpdate(WindowPtr window);
switch ( event->what ) {
case mouseDown:
part = FindWindow(event->where, &window);
switch ( part ) {
case inMenuBar:
StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
AdjustMenus();
DoMenuCommand(MenuSelect(event->where));
StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
break;
case inSysWindow:
SystemClick(event, window);
break;
case inContent:
if ( window != FrontWindow() )
SelectWindow(window);
if (MouseDownInSensor((GEWorldPtr) GetWRefCon(gAnimWindow), event->where))
;;
break;
case inDrag:
DragWindow(window, event->where, &qd.screenBits.bounds);
break;
case inGrow:
newWSize = GrowWindowConstrained(window, event->where,
&gWorldLimRect, &gWorldBaseRect);
SizeWindow(window, LoWord(newWSize), HiWord(newWSize), true);
ChangeWorldSize(window, LoWord(newWSize), HiWord(newWSize));
InvalRect(&((GrafPtr)window)->portRect);
break;
}
break;
case keyDown:
key = event->message & charCodeMask;
if ( event->modifiers & cmdKey ) {
StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
AdjustMenus();
DoMenuCommand(MenuKey(key));
StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
}
gDoOne = true;
break;
case activateEvt:
DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
break;
case updateEvt:
DoUpdate((WindowPtr) event->message);
break;
case osEvt:
switch ((event->message >> 24) & 0x0FF) {
case suspendResumeMessage:
gInBackground = (event->message & resumeFlag) == 0;
DoActivate(FrontWindow(), !gInBackground);
break;
}
break;
}
}
void DoActivate(WindowPtr window, Boolean becomingActive)
{
#pragma unused (window)
#pragma unused (becomingActive)
//Could start and stop animation here
}
void DoUpdate(WindowPtr window)
{
Rect geRect;
GEWorldPtr geWorld;
if (window == gAnimWindow)
{
SetPort( (GrafPtr) window );
BeginUpdate(window);
DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), true);
EndUpdate(window);
}
}
void AdjustMenus( void )
{
WindowPtr window;
MenuHandle menu;
window = FrontWindow();
menu = GetMHandle(mFile);
EnableItem(menu, iQuit);
menu = GetMHandle(mEdit);
if (window = gAnimWindow) {
DisableItem(menu, iUndo);
DisableItem(menu, iCut);
DisableItem(menu, iCopy);
DisableItem(menu, iClear);
DisableItem(menu, iPaste);
}
else {
EnableItem(menu, iUndo);
EnableItem(menu, iCut);
EnableItem(menu, iCopy);
EnableItem(menu, iClear);
EnableItem(menu, iPaste);
}
menu = GetMHandle(mSpecial);
// Set up special items!
EnableItem(menu, iTiming);
EnableItem(menu, iMeter);
CheckItem(menu, iMeter, gMeterShown);
EnableItem(menu, iPlayMovie);
CheckItem(menu, iPlayMovie, gMoviePlaying);
EnableItem(menu, iSoundActive);
CheckItem(menu, iSoundActive, gSoundActive);
}
void DoMenuCommand(long menuResult)
{
short menuID;
short menuItem;
Str255 daName;
short daRefNum;
menuID = HiWord(menuResult);
menuItem = LoWord(menuResult);
switch ( menuID ) {
case mApple:
switch ( menuItem ) {
case iAbout:
PutUpAboutBox((GEWorldPtr) GetWRefCon(gAnimWindow));
break;
default: /* all other items in this menu are DAs */
GetItem(GetMHandle(mApple), menuItem, daName);
daRefNum = OpenDeskAcc(daName);
break;
}
break;
case mFile:
if (menuItem == iQuit)
gFinished = true;
break;
case mEdit:
(void) SystemEdit(menuItem-1);
break;
case mSpecial:
//Add special items
switch ( menuItem ) {
case iTiming:
DoTimingLoop();
break;
case iMeter:
gMeterShown = !gMeterShown;
ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterBkgID, gMeterShown);
ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterIndID, gMeterShown);
break;
case iSingleFrame:
gSingleFrame = !gSingleFrame;
break;
case iPlayMovie:
gMoviePlaying = !gMoviePlaying;
PlayGEMovie((GEWorldPtr) GetWRefCon(gAnimWindow), gMoviePlaying);
break;
case iSoundActive:
{
GEWorldPtr world = (GEWorldPtr) GetWRefCon(gAnimWindow);
GESoundPtr sounds = (GESoundPtr) world->userData;
gSoundActive = !gSoundActive;
GEnableSound(sounds, gSoundActive);
}
break;
}
break;
}
HiliteMenu(0);
}
void AdjustCursor( void )
{
WindowPtr window;
window = FrontWindow();
if ( (window == gAnimWindow) && (!gInBackground) ) {
SetCursor(&qd.arrow);
}
}